home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / alpha / dipc / dipc-0.000 / dipc-0 / dipc-0.15 / dipcd / back_end.c < prev    next >
C/C++ Source or Header  |  1996-07-16  |  9KB  |  365 lines

  1. /*
  2.  * back_end.c
  3.  *
  4.  * part of dipcd source code
  5.  *
  6.  * Copyright (C) Kamran Karimi
  7.  */
  8.  
  9. #include "dipcd.h"
  10. #include "funcs.h"
  11.  
  12. /* back_end forks the necessary processes and the sleep in the kernel, 
  13.    wait for work to become available. It then forks an employer to handle
  14.    it */
  15.  
  16. struct sockaddr_in MY_LBACK, REFEREE_LBACK;
  17. struct sockaddr_in MY_ADDRESS, REFEREE_ADDRESS;
  18.  
  19. int verbose;
  20. int global_timeout;
  21. int employer_referee_timeout;
  22. int employer_shm_timeout;
  23. int employer_worker_timeout;
  24. int referee_timeout;
  25. int shm_ak_timeout;
  26. double shm_hold_timeout;
  27.  
  28. /* used in parsing dipcd configuration file */ 
  29. static void strip_space(char *buff)
  30. {
  31.  char buff2[160];
  32.  int count, count2 = 0;
  33.  
  34.  for(count = 0; count < strlen(buff); count++)
  35.  {
  36.   if(buff[count] == ' ' || buff[count] == '\t')
  37.    continue;
  38.   buff2[count2] = buff[count];
  39.   count2++;
  40.  }
  41.  buff2[count2] = 0;
  42.  strcpy(buff, buff2);
  43. }
  44.  
  45. /* read my address and the referee address, plus time-out values and put them 
  46.    in globaly known variables */
  47. static BOOLEAN init_dipc(void)
  48. {
  49.  long count;
  50.  char *pos, buff[160];
  51.  FILE *file;
  52.  struct in_addr addr;
  53.  
  54.  /* default values */
  55.  employer_referee_timeout = EMPLOYER_REFEREE_TIMEOUT;
  56.  employer_shm_timeout = EMPLOYER_SHM_TIMEOUT;
  57.  employer_worker_timeout = EMPLOYER_WORKER_TIMEOUT;
  58.  shm_ak_timeout = SHM_AK_TIMEOUT;
  59.  referee_timeout = REFEREE_TIMEOUT;
  60.  shm_hold_timeout = SHM_HOLD_TIMEOUT;
  61.  /* the address of this computer and the referee's computer SHOULD be 
  62.  given */ 
  63.  REFEREE_ADDRESS.sin_addr.s_addr = -1;
  64.  MY_ADDRESS.sin_addr.s_addr = -1;
  65.  
  66.  addr.s_addr = -1;
  67.  file = fopen(CONFIG_FILE,"r");
  68.  if(file == NULL) 
  69.  {
  70.   sprintf(mstr,"ERROR: Can't Open Config File %s  BECAUSE %s",
  71.                                        CONFIG_FILE, strerror(errno));
  72.   mess(mstr, INFO);
  73.   return FAIL;
  74.  } 
  75.  while(fgets(buff,80,file))
  76.  {
  77.   pos = strchr(buff, '#'); /* no comments */
  78.   if(pos) *pos = 0;
  79.   strip_space(buff);
  80.   pos = strchr(buff, '=');
  81.   if(pos == NULL) continue;
  82.   *pos = 0;
  83.   if(!strcasecmp(buff,"this_machine"))
  84.   {
  85.    pos++;
  86.    count = 0;
  87.    while((count < strlen(pos)) && !isdigit(pos[count])) count++;
  88.    addr.s_addr = inet_addr(&pos[count]);
  89.    if((addr.s_addr != -1) && strcasecmp((char *)inet_ntoa(addr),"0.0.0.0"))
  90.    { 
  91.     bzero((char *)&MY_ADDRESS, sizeof(MY_ADDRESS));
  92.     MY_ADDRESS.sin_family = AF_INET;
  93.     MY_ADDRESS.sin_addr.s_addr = addr.s_addr;
  94.     MY_ADDRESS.sin_port = htons(DIPC_TCP_PORT);
  95.    } 
  96.   }
  97.   else if(!strcasecmp(buff,"referee"))
  98.   {
  99.    pos++;
  100.    count = 0;
  101.    while((count < strlen(pos)) && !isdigit(pos[count])) count++;
  102.    addr.s_addr = inet_addr(&pos[count]);
  103.    if((addr.s_addr != -1) && strcasecmp((char *)inet_ntoa(addr),"0.0.0.0"))
  104.    { 
  105.     bzero((char *)&REFEREE_ADDRESS, sizeof(REFEREE_ADDRESS));
  106.     REFEREE_ADDRESS.sin_family = AF_INET;
  107.     REFEREE_ADDRESS.sin_addr.s_addr = addr.s_addr;
  108.     REFEREE_ADDRESS.sin_port = htons(DIPC_REFEREE_PORT);
  109.    }
  110.   }
  111.   else if(!strcasecmp(buff,"employer_referee_timeout"))
  112.   { 
  113.    pos++;
  114.    employer_referee_timeout = atoi(pos);  
  115.   }
  116.   else if(!strcasecmp(buff,"employer_shm_timeout"))
  117.   { 
  118.    pos++;
  119.    employer_shm_timeout = atoi(pos);  
  120.   }
  121.   else if(!strcasecmp(buff,"employer_worker_timeout"))
  122.   { 
  123.    pos++;
  124.    employer_worker_timeout = atoi(pos); 
  125.   }
  126.   else if(!strcasecmp(buff,"shm_ak_timeout"))
  127.   { 
  128.    pos++;
  129.    shm_ak_timeout = atoi(pos);
  130.   } 
  131.   else if(!strcasecmp(buff,"referee_timeout"))
  132.   { 
  133.    pos++;
  134.    referee_timeout = atoi(pos);  
  135.   }
  136.   else if(!strcasecmp(buff,"shm_hold_timeout"))
  137.   { 
  138.    pos++;
  139.    shm_hold_timeout = atoi(pos);
  140.    if(shm_hold_timeout <= 0)
  141.     shm_hold_timeout = SHM_HOLD_TIMEOUT;
  142.   }
  143.   else
  144.   {
  145.    sprintf(mstr,"ERROR: Unknown option %s",buff);    
  146.    mess(mstr, INFO);
  147.   }
  148.  }
  149.  if(REFEREE_ADDRESS.sin_addr.s_addr == -1)
  150.  {
  151.   sprintf(mstr,"ERROR: Can't Find Referee's Address");
  152.   mess(mstr, INFO);
  153.   return FAIL;
  154.  } 
  155.  if(MY_ADDRESS.sin_addr.s_addr == -1)
  156.  {
  157.   sprintf(mstr,"ERROR: Can't Find My Own Address");
  158.   mess(mstr, INFO);
  159.   return FAIL;
  160.  }        
  161.  bzero((char *)&REFEREE_LBACK, sizeof(REFEREE_LBACK));
  162.  REFEREE_LBACK.sin_family = AF_INET;
  163.  REFEREE_LBACK.sin_addr.s_addr = htonl(INADDR_ANY);
  164.  REFEREE_LBACK.sin_port = htons(DIPC_REFEREE_PORT);
  165.  
  166.  bzero((char *)&MY_LBACK, sizeof(MY_LBACK));
  167.  MY_LBACK.sin_family = AF_INET;
  168.  MY_LBACK.sin_addr.s_addr = htonl(INADDR_ANY);
  169.  MY_LBACK.sin_port = htons(DIPC_TCP_PORT);
  170.  
  171.  if(verbose)
  172.  {
  173.   sprintf(mstr,"employer_worker Timeout is %d secs",employer_worker_timeout);
  174.   mess(mstr, INFO);
  175.   sprintf(mstr,"employer_shm Timeout is %d secs",employer_shm_timeout);
  176.   mess(mstr, INFO);
  177.   sprintf(mstr,"employer_referee Timeout is %d secs",employer_referee_timeout);
  178.   mess(mstr, INFO);
  179.   sprintf(mstr,"shm_ak Timeout is %d secs",shm_ak_timeout);  
  180.   mess(mstr, INFO);
  181.   sprintf(mstr,"referee Timeout is %d secs",referee_timeout);
  182.   mess(mstr, INFO);
  183.   sprintf(mstr,"shm_hold Timeout is %f secs",shm_hold_timeout);
  184.   mess(mstr, INFO);
  185.  }
  186.  return SUCCESS;
  187. }
  188.  
  189.  
  190. static void sig_handler(int signo)
  191. {
  192.  if(verbose)
  193.  {
  194.   sprintf(mstr,"Quiting For Signal No. %d",signo);
  195.   mess(mstr, INFO);
  196.  } 
  197.  if(dipc(0,DIPC_REMMNG,NULL) != DIPC_SUCCESS)
  198.  {
  199.   sprintf(mstr,"ERROR: DIPC_REMMNG failed");
  200.   mess(mstr, INFO);
  201.  } 
  202.  /* do last works */
  203.  
  204.  exit(5);
  205. }
  206.  
  207.  
  208. void main(int argc, char **argv)
  209. {
  210.  int count;
  211.  struct dipc_info di;
  212.  char data[MAXDATA];
  213.  void *pt[2];
  214.  pid_t child_pid;    
  215.  struct sigaction sact;
  216.  struct sockaddr_in in_addr;
  217.  int in_len, in_sockfd;
  218.  int found_work;
  219.  
  220.  if(getuid() != 0)
  221.  {
  222.   sprintf(mstr,"ERROR: dipcd can not run without root privileges");
  223.   mess(mstr, INFO);
  224.   exit(20);
  225.  } 
  226.  if(fork() > 0)
  227.   exit(0); 
  228.  chdir("/");
  229.  
  230.  bzero((char *)&in_addr,sizeof(in_addr));
  231.  in_addr.sin_family = AF_INET;
  232.  in_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  233.  in_addr.sin_port = htons(DIPC_TCP_PORT);
  234.  in_len = sizeof(in_addr);
  235.  in_sockfd = plug(AF_INET, (struct sockaddr *) &in_addr, in_len);
  236.  if(in_sockfd < 0)
  237.  {
  238.   sprintf(mstr,"ERROR: dipcd Is Already Running");
  239.   mess(mstr, INFO);
  240.   exit(20);
  241.  }
  242.  close(in_sockfd);
  243.  sprintf(mstr,"%s Version %s Started", argv[0], DIPC_VERSION);
  244.  mess(mstr, INFO);
  245.  verbose = 0;
  246.  global_timeout = 1;
  247.  for(count = 1; count < argc; count++)
  248.  {
  249.   if(argv[count][0] == '-')
  250.   {
  251.    if(argv[count][1] == 'v')
  252.     verbose = 1;
  253.    else if(argv[count][1] == 't')
  254.     global_timeout = 0;    
  255.   }  
  256.  }
  257.  sact.sa_handler = sig_handler;
  258.  sigemptyset(&sact.sa_mask);
  259.  sact.sa_flags = 0;
  260.   
  261.  if(sigaction(SIGINT, &sact, NULL) < 0)
  262.  {
  263.   sprintf(mstr,"ERROR: Can't Catch Signal BECAUSE %s",strerror(errno));
  264.   mess(mstr, INFO);
  265.  } 
  266.  if(sigaction(SIGTERM, &sact, NULL) < 0)
  267.  {
  268.   sprintf(mstr,"ERROR: Can't Catch Signal  BECAUSE %s",strerror(errno));
  269.   mess(mstr, INFO);
  270.  } 
  271.  if(sigaction(SIGSEGV, &sact, NULL) < 0)
  272.  {
  273.   sprintf(mstr,"ERROR: Can't Catch Signal BECAUSE %s",strerror(errno));
  274.   mess(mstr,INFO);
  275.  }
  276.  sact.sa_handler = child_handler;
  277.  if(sigaction(SIGCHLD, &sact, NULL) < 0)
  278.  {
  279.   sprintf(mstr,"ERROR: Can't Catch Signal  BECAUSE %s",strerror(errno));
  280.   mess(mstr, INFO);
  281.  }
  282.  pt[0] = &di;
  283.  pt[1] = data;
  284.  
  285.  if(init_dipc() == FAIL) exit(20);
  286.  /* register this task as the official dipcd task, responsible for handling 
  287.     DIPC requests */
  288.  if(dipc(MY_ADDRESS.sin_addr.s_addr, DIPC_SETMNG,NULL) < DIPC_SUCCESS)
  289.  {
  290.   sprintf(mstr,"ERROR: DIPC_SETMNG failed");
  291.   mess(mstr, INFO);
  292.   exit(20);
  293.  }
  294.  /* start the front_end task */
  295.  if((child_pid = fork()) < 0)
  296.  {
  297.   sprintf(mstr,"ERROR: Can't fork()  BECAUSE %s",strerror(errno));
  298.   mess(mstr, INFO);
  299.   dipc(0,DIPC_REMMNG,NULL);
  300.   exit(20);
  301.  }
  302.  else if(child_pid == 0)
  303.  {
  304.   front_end();
  305.   exit(20); /* never reaches here */
  306.  } 
  307.  /* see if this is the referee machine */
  308.  if(SAME_MACHINE(&MY_ADDRESS,REFEREE_ADDRESS))
  309.  {
  310.   if((child_pid = fork()) < 0)
  311.   {
  312.    sprintf(mstr,"ERROR: Can't fork()  BECAUSE %s",strerror(errno));
  313.    mess(mstr, INFO);
  314.    dipc(0,DIPC_REMMNG,NULL);
  315.    exit(20);
  316.   }
  317.   else if(child_pid == 0)
  318.   {
  319.    referee();
  320.    exit(20);
  321.   }
  322.  } 
  323.  
  324.  while(1) 
  325.  { 
  326.   if(dipc(0, DIPC_SLEEP, 0) != DIPC_SUCCESS)
  327.   {
  328.    sprintf(mstr,"ERROR: DIPC_SLEEP failed");
  329.    mess(mstr, INFO);
  330.   } 
  331.   found_work = dipc(0,DIPC_GETWORK, pt);
  332.   if(found_work < DIPC_SUCCESS)
  333.   {
  334.    sprintf(mstr,"ERROR: DIPC_GETWORK failed");
  335.    mess(mstr, INFO);
  336.   }
  337.   else if(found_work == DIPC_SUCCESS)
  338.   {
  339.    if(verbose)
  340.    {
  341.     sprintf(mstr,"Found work: %s",work_string(di.func));
  342.     mess(mstr, INFO);
  343.    } 
  344.    /* only non-local requests will be returned, so create a handler 
  345.       (employer) for them */
  346.    if((child_pid = fork()) < 0)
  347.    {
  348.     sprintf(mstr,"ERROR: Can't fork()  BECAUSE %s",strerror(errno));    
  349.     mess(mstr, INFO);
  350.     di.arg1 = -DIPC_E_FORK;
  351.     if(dipc(di.pid, DIPC_RETWORK, (int *)pt) < DIPC_SUCCESS)
  352.     {
  353.      sprintf(mstr,"ERROR: DIPC_RETWORK failed");
  354.      mess(mstr, INFO);
  355.     }
  356.    } 
  357.    else if(child_pid == 0)
  358.    {
  359.     employer(&di, data);
  360.     exit(20);
  361.    }
  362.   }
  363.  } /* while(1) */
  364. }
  365.